import {Fetcher, Route, Token} from '@uniswap/sdk';
import {Configuration} from './config';
import {ContractName, TokenStat, TreasuryAllocationTime} from './types';
import {BigNumber, Contract, ethers, Overrides} from 'ethers';
import {decimalToBalance} from './ether-utils';
import {TransactionResponse} from '@ethersproject/providers';
import ERC20 from './ERC20';
import {getDisplayBalance} from '../utils/formatBalance';
import {getDefaultProvider} from '../utils/provider';
import IUniswapV2PairABI from './IUniswapV2Pair.abi.json';
import config, {bankDefinitions} from '../config';
import {getCache, setCache} from './cache';
import {delay} from 'q';
import {CommonTvl, FishLp, TimeStatus} from "../common/common";

/**
 * An API module of Super Nova contracts.
 * All contract-interacting domain logic should be defined in here.
 */
export class BasisCash {
  myAccount: string;
  provider: ethers.providers.Web3Provider;
  signer?: ethers.Signer;
  config: Configuration;
  contracts: { [name: string]: Contract };
  externalTokens: { [name: string]: ERC20 };
  boardroomVersionOfUser?: string;

  bacDai: Contract;
  linshiBJ: ERC20;
  sCASH: ERC20;
  SHARE: ERC20;
  SNB: ERC20;
  sCASH_SHARE_LP: ERC20;
  sHT_SHARE_LP: ERC20;
  LP1: ERC20;
  sFUND_USDT: ERC20;
  sFUND_SCASH: ERC20;
  sFUND_SHT: ERC20;
  sFUND_WHT: ERC20;
  sFUND_PNEO: ERC20;
  sCASH_USDT_LP: ERC20;
  sCASH_PegPool: ERC20;
  sHT: ERC20;
  // HUSD_POOL: ERC20;
  HUSD:ERC20;
  YNC_USDT_LP:ERC20;
  YNC:ERC20;
  NYC:ERC20;
  NYC_USDT_LP:ERC20;
  priceConfigs: {[key: string]: number};
  wHTConfigs: string[];
  NULSConfigs: string[];
  USDTConfigs: string[];
  fConfigs: {[key: string]: string};

  constructor(cfg: Configuration) {
    const { deployments, externalTokens } = cfg;
    const provider = getDefaultProvider();

    this.wHTConfigs = [''];
    this.USDTConfigs = ['NULS'];
    this.NULSConfigs = ['sNULS'];
    this.fConfigs = {
      'fHBTC': 'HBTC',
      'fETH': 'wETH',
      'fHT': 'wHT',
      'fNEO': 'pNEO',
      'fHFIL': 'HFIL',
      'fHDOT': 'HDOT',
      'fHLTC': 'HLTC',
      'fMDX': 'MDX',
      'fELA': 'ELA',
    };

    this.priceConfigs = {
      'USDT': 1,
      'HUSD': 1,
      //'HBTC': 49363,
      //'wETH': 1642,
      //'wHT': 16.2,
      //'pNEO': 41.74,
      //'HFIL': 36.94,
      //'HDOT': 34.63,
      //'HLTC': 181.41,
      //'BAG': 1,

      'fHUSD': 0.025,
      'fUSDT': 0.025,
      //'fHBTC': 49363 / 45,
      //'fETH': 1642 / 45,
      //'fHT': 19.37 / 45,
      //'fNEO': 41.74 / 45,
      //'fHFIL': 36.94 / 45,
      //'fHDOT': 34.63 / 45,
      //'fHLTC': 181.41 / 45,
      //'Filda': 1.7,
      //'TPT': 0.05,

      //'sHT': 180,
      //'MDX': 4.9,
      //'HBO': 2.5,
      //'LHB': 0.6,
      //'sCASH': 2,
      //'NULS': 0.53
      'pFLM': 0.48,
      'pSWTH': 0.048,
      'sCAN': 100,
      'sFLM': 100,
      'ELA': 6.4,
      'fELA': 6.4 / 45,
      'SWFTC': 0.001095,
      'ARCH': 0.005,
      'GOBLIN': 0.15,
      'YNC':0.003
    };

    // loads contracts from deployments
    this.contracts = {};
    for (const [name, deployment] of Object.entries(deployments)) {
      this.contracts[name] = new Contract(deployment.address, deployment.abi, provider);
    }
    this.externalTokens = {};
    for (const [symbol, [address, decimal]] of Object.entries(externalTokens)) {
      this.externalTokens[symbol] = new ERC20(address, provider, symbol, decimal); // TODO: add decimal
    }

    console.log('deployments',deployments,externalTokens)
    this.YNC = new ERC20(deployments.YNC.address, provider, 'YNC');
    this.YNC_USDT_LP = new ERC20(deployments.YNC_USDT_LP.address, provider, 'YNC_USDT_LP');
    this.NYC = new ERC20(deployments.NYC.address, provider, 'NYC');
    this.NYC_USDT_LP = new ERC20(deployments.NYC_USDT_LP.address, provider, 'NYC_USDT_LP');

    this.sCASH = new ERC20(deployments.sCASH.address, provider, 'sCASH');
    this.SHARE = new ERC20(deployments.SHARE.address, provider, 'SHARE');
    this.SNB = new ERC20(deployments.SHARE.address, provider, 'SNB');

    this.HUSD = new ERC20(externalTokens.HUSD[0], provider, 'HUSD');
    // this.HUSD_POOL = new ERC20(deployments.HUSD_POOL.address, provider, 'HUSD_POOL');

    this.sFUND_USDT = new ERC20(externalTokens.USDT[0], provider, 'sFUND_USDT');
    this.sFUND_SCASH = new ERC20(externalTokens.sCASH[0], provider, 'sFUND_SCASH');
    this.sCASH_USDT_LP = new ERC20(externalTokens.sCASH_USDT_LP[0], provider, 'sCASH_USDT_LP');


    this.sFUND_SHT = new ERC20(externalTokens.sHT[0], provider, 'sFUND_SHT');
    this.sFUND_WHT = new ERC20(externalTokens.wHT[0], provider, 'sFUND_WHT');
    this.sFUND_PNEO = new ERC20(externalTokens.pNEO[0], provider, 'sFUND_PNEO', externalTokens.pNEO[1]);

    this.sHT = new ERC20(externalTokens.sHT[0], provider, 'sHT');
    this.sCASH_PegPool = new ERC20(deployments.sCASH_PegPool.address, provider, 'sCASH_PegPool');
    // Uniswap V2 Pair
    this.bacDai = new Contract(
      externalTokens['sCASH_USDT_LP'][0],
      IUniswapV2PairABI,
      provider,
    );

    this.config = cfg;
    this.provider = provider;
  }

  /**
   * @param provider From an unlocked wallet. (e.g. Metamask)
   * @param account An address of unlocked wallet account.
   */
  unlockWallet(provider: any, account: string) {
    const newProvider = new ethers.providers.Web3Provider(provider, this.config.chainId);

    this.signer = newProvider.getSigner(0);
    this.myAccount = account;
    for (const [name, contract] of Object.entries(this.contracts)) {
      this.contracts[name] = contract.connect(this.signer);
    }
    const tokens = [this.sCASH, this.SHARE, this.SNB, this.sHT, ...Object.values(this.externalTokens)];
    for (const token of tokens) {
      token.connect(this.signer);
    }
    this.bacDai = this.bacDai.connect(this.signer);

    console.log(`🔓 Wallet is unlocked. Welcome, ${account}!`);
    this.fetchBoardroomVersionOfUser()
      .then((version) => (this.boardroomVersionOfUser = version))
      .catch((err) => {
        console.error(`Failed to fetch boardroom version: ${err.stack}`);
        this.boardroomVersionOfUser = 'latest';
      });

  }

  get isUnlocked(): boolean {
    return !!this.myAccount;
  }

  gasOptions(gas: BigNumber): Overrides {
    const multiplied = Math.floor(gas.toNumber() * this.config.gasLimitMultiplier);
    console.log(`⛽️ Gas multiplied: ${gas} -> ${multiplied}`);
    return {
      gasLimit: BigNumber.from(multiplied),
    };
  }

  /**
   * @returns Super Nova (sCASH) stats from Uniswap.
   * It may differ from the sCASH price used on Treasury_sCASH (which is calculated in TWAP)
   */
  async getCashStatFromUniswap(): Promise<TokenStat> {
    const supply = await this.sCASH.displayedTotalSupply();
    return {
      priceInDAI: await this.getTokenPriceFromUniswap(this.sCASH),
      totalSupply: supply,
    };
  }

  async getHusdPoolStat(token:string,v2:boolean): Promise<any> {
    // const v2 = useV1();
    const erc20Token = this.externalTokens[token];
    let pool = token+'_POOL';
    if(!v2){
      pool = token+'_POOL_OLD';
    }
    let contract = this.contracts[pool];
    // console.log(v2,'getHusdPoolStat')

    const decimal = erc20Token.decimal || 18;

    const midPrice: number = (await this.getPrice(token)) || 0;
    const totalSupply = (await contract.totalSupply()) || BigNumber.from(0);
    const tvl = ethers.utils.formatUnits(BigNumber.from(parseInt((midPrice * 10000).toString())).mul(totalSupply).div(10000), erc20Token.decimal);
    CommonTvl[token] = Number(tvl);
    const myDepo = (await contract.balanceOf(this.myAccount)) || BigNumber.from(0);
    const earned = (await contract.earned(this.myAccount)) || BigNumber.from(0);
    const dailyReward:number = Number(ethers.utils.formatUnits(await contract.rewardRate())) || 0;
    const totalReward:number = Number(ethers.utils.formatUnits(await contract.rewardTotal())) || 0;
    const apy = Number(await this.getYNCApy(pool,erc20Token,tvl,v2)) || 0;
    const tokenBalance:BigNumber = await erc20Token.balanceOf(this.myAccount);
    const myBalance = getDisplayBalance(tokenBalance, decimal);
    const startTime = parseInt((await contract.starttime()).toString());
    const durationTime = parseInt((await contract.duration()).toString());
    const addr = contract.address;
    const endTime = startTime+durationTime;
    let timeStatus = TimeStatus.NOT_START;
    if(Date.now()/1000>endTime){
      timeStatus = TimeStatus.FINISHED;
    }else if(Date.now()/1000<endTime && Date.now()/1000>startTime){
      timeStatus = TimeStatus.STARTING;
    }
    if(timeStatus===TimeStatus.FINISHED){
      return {
        tvl:"0.0000",
        totalSupply: "0.0000",
        myDepo: "0.0000",
        earned: "0.0000",
        dailyReward: "0.0000",
        totalReward: "0.0000",
        apy:'0.0000%',
        apr:'0.0000%',
        myBalance:"0.0000",
        timeStatus,
        addr
      }
    }
    return {
      tvl:Number(tvl).toFixed(4),
      totalSupply: Number(getDisplayBalance(totalSupply,decimal)).toFixed(4),
      myDepo: Number(getDisplayBalance(myDepo,decimal)).toFixed(4),
      earned: Number(getDisplayBalance(earned)).toFixed(4),
      dailyReward: (dailyReward*86400).toFixed(0),
      totalReward: totalReward.toFixed(0),
      apy:(apy*100).toFixed(2)+'%',
      apr:Math.min(999999, (Math.pow(1+Number(apy)/365, 365)-1)*100).toFixed(2) + '%',
      myBalance:Number(myBalance).toFixed(4),
      timeStatus,
      addr
    };
  }

  async getNftPoolStat(token:string): Promise<any> {
    // const v2 = useV1();
    const erc20Token = this.externalTokens[token];
    let pool = token+'_FishCardPool';
    let contract = this.contracts[pool];
    // console.log(v2,'getHusdPoolStat')
    const decimal = erc20Token.decimal || 18;

    const midPrice: number = (await this.getPrice(token)) || 0;
    const totalSupply = (await contract.totalSupply()) || BigNumber.from(0);
    let tvl = ethers.utils.formatUnits(BigNumber.from(parseInt((midPrice * 10000).toString())).mul(totalSupply).div(10000), erc20Token.decimal);
    if(token.indexOf('LP')>-1){
      tvl = await this.getTVLPre(erc20Token.address, pool, erc20Token.symbol)
    }
    // CommonTvl[token] = Number(tvl);
    console.log(token,tvl,"-----")
    const myDepo = (await contract.balanceOf(this.myAccount)) || BigNumber.from(0);
    const earned = (await contract.earned(this.myAccount)) || BigNumber.from(0);
    const dailyReward:number = Number(ethers.utils.formatUnits(await contract.rewardRate())) || 0;
    const totalReward:number = Number(ethers.utils.formatUnits(await contract.rewardTotal())) || 0;
    const apy = Number(await this.getYNCApy(pool,erc20Token,tvl, true)) || 0;
    const tokenBalance:BigNumber = await erc20Token.balanceOf(this.myAccount);
    const myBalance = getDisplayBalance(tokenBalance, decimal);
    const startTime = parseInt((await contract.starttime()).toString());
    const durationTime = parseInt((await contract.duration()).toString());
    const addr = contract.address;
    const endTime = startTime+durationTime;
    let timeStatus = TimeStatus.NOT_START;
    if(Date.now()/1000>endTime){
      timeStatus = TimeStatus.FINISHED;
    }else if(Date.now()/1000<endTime && Date.now()/1000>startTime){
      timeStatus = TimeStatus.STARTING;
    }
    if(timeStatus===TimeStatus.FINISHED){
      return {
        tvl:"0.0000",
        totalSupply: "0.0000",
        myDepo: "0.0000",
        earned: "0.0000",
        dailyReward: "0.0000",
        totalReward: "0.0000",
        apy:'0.0000%',
        apr:'0.0000%',
        myBalance:"0.0000",
        timeStatus,
        addr
      }
    }
    return {
      tvl:Number(tvl).toFixed(4),
      totalSupply: Number(getDisplayBalance(totalSupply,decimal)).toFixed(4),
      myDepo: Number(getDisplayBalance(myDepo,decimal)).toFixed(4),
      earned: Number(getDisplayBalance(earned)).toFixed(4),
      dailyReward: (dailyReward*86400).toFixed(0),
      totalReward: totalReward.toFixed(0),
      apy:(apy*100).toFixed(2)+'%',
      apr:Math.min(999999, (Math.pow(1+Number(apy)/365, 365)-1)*100).toFixed(2) + '%',
      myBalance:Number(myBalance).toFixed(4),
      timeStatus,
      addr
    };
  }

  async showStore(pool: string): Promise<any> {
    const colors: any = {0: '绿', 1: '蓝', 2: '红', 3: '紫',4:"粉", 5: '黑',6:"白",7:"金"}
    let contract = this.contracts['FishCardStore'];
    console.log('contract', contract);
    const fishDnas = await contract.getFishDnas();
    console.log('fishDnas', fishDnas);
    const fishColor = await contract.getFishColor();
    console.log('fishColor', fishColor);
    const obj: any[] = await contract.showStore(this.contracts[pool].address);
    return obj.filter(item => ![4, 6, 7].includes(item.fishLevel)).map(item => {
      return {
        fishLevel: item.fishLevel,
        color: item.fishLevel,
        fishTypeNumber: item.fishTypeNumber,
        overTime: Number(item.overTime).toFixed(0),
        price: Number(getDisplayBalance(item.price)).toFixed(0),
        total: Number(item.total).toFixed(0),
      }
    });
  }

  async getOwnerOf(): Promise<any> {
    const colors: any = {0: '绿', 1: '蓝', 2: '红', 3: '紫', 5: '黑'}
    let contract = this.contracts['FishCard'];
    console.log('contract', contract);
    const obj: any[] = await contract.getOwnerOf();
    const fishes: any[] = [];
    for(let i=0;i<obj.length;i++) {
      const item = await contract.getFishDetail(BigNumber.from(obj[i]));
      const itemDna = await contract.getFishDna(BigNumber.from(obj[i]));
      console.log(itemDna,'dna')
      fishes.push({
        fishLevel: item._fishLevel,
        color: item._fishLevel,
        fishTypeNumber: item._fishTypeNumber,
        price: Number(getDisplayBalance(item._price)).toFixed(0),
        createTime: getDisplayBalance(item._createTime),
        stake: Number(getDisplayBalance(item._stake)).toFixed(0),
        number: Number(item._number).toFixed(0),
        dna:itemDna._dna,
        a:itemDna._a,
        b:itemDna._b,
        c:itemDna._c,
        d:itemDna._d,
        perfect:itemDna._perfect
      });
    }
    return fishes;
  }
  async getOwnerOfLast(): Promise<any> {
    let contract = this.contracts['FishCard'];
    const obj: any[] = await contract.getOwnerOf();
    let data = obj[obj.length-1] || "";
    const item = await contract.getFishDetail(BigNumber.from(data));
    const itemDna = await contract.getFishDna(BigNumber.from(data));
    return {
      fishLevel: item._fishLevel,
      color: item._fishLevel,
      fishTypeNumber: item._fishTypeNumber,
      price: Number(getDisplayBalance(item._price)).toFixed(0),
      createTime: getDisplayBalance(item._createTime),
      stake: Number(getDisplayBalance(item._stake)).toFixed(0),
      number: Number(item._number).toFixed(0),
      dna:itemDna._dna,
      a:itemDna._a,
      b:itemDna._b,
      c:itemDna._c,
      d:itemDna._d,
      perfect:itemDna._perfect
    };
  }
  async getMyStake(color:number): Promise<any> {
    const contract = this.contracts['FishCard'];
    const poolName = FishLp[color]+'_NFTRewardPool';
    const pool = this.contracts[poolName];
    console.log('contract', contract);
    const obj: any[] = await pool.myStake();
    const fishes: any[] = [];
    for(let i=0;i<obj.length;i++) {
      const item = await contract.getFishDetail(BigNumber.from(obj[i]));
      const itemDna = await contract.getFishDna(BigNumber.from(obj[i]));
      console.log(itemDna,'dna')
      fishes.push({
        fishLevel: item._fishLevel,
        color: item._fishLevel,
        fishTypeNumber: item._fishTypeNumber,
        price: Number(getDisplayBalance(item._price)).toFixed(0),
        createTime: getDisplayBalance(item._createTime),
        stake: Number(getDisplayBalance(item._stake)).toFixed(0),
        number: Number(item._number).toFixed(0),
        dna:itemDna._dna,
        a:itemDna._a,
        b:itemDna._b,
        c:itemDna._c,
        d:itemDna._d,
        perfect:itemDna._perfect
      });
    }
    return fishes;
  }
  async getYncLpStat(token:string): Promise<any> {
    const erc20Token = this.externalTokens["YNC_USDT_LP"];
    const contract = this.contracts['YNC_LP_REWARD_POOL'];
    const oldContract = this.contracts['YNC_LP_REWARD_POOL_OLD'];
    // const contractOld = this.contracts['YNC_LP_REWARD_POOL_Old'];
    const decimal = erc20Token.decimal || 18;
    const midPrice: number = (await this.getYNCPrice()) || 0;
    //const midPrice: number = (await this.getPrice(token)) || 0;
    const totalSupply = (await contract.totalSupply()) || BigNumber.from(0);
    //const tvl = ethers.utils.formatUnits(BigNumber.from(parseInt((midPrice * 10000).toString())).mul(totalSupply).div(10000), erc20Token.decimal);
    const tvl = await this.getTVLPre(erc20Token.address, 'YNC_LP_REWARD_POOL', erc20Token.symbol);
    CommonTvl["YNC_USDT_LP"] = Number(tvl);
    const myDepo = (await contract.balanceOf(this.myAccount)) || BigNumber.from(0);
    const myDepoOld = (await oldContract.balanceOf(this.myAccount)) || BigNumber.from(0);
    const earned = (await contract.earned(this.myAccount)) || BigNumber.from(0);
    // const earnedOld = (await contractOld.earned(this.myAccount)) || BigNumber.from(0);
    const lavaEarned = (await this.earnedLavaP("YNC_LP_REWARD_POOL")) || BigNumber.from(0);
    const dailyReward:number = Number(ethers.utils.formatUnits(await contract.rewardRate())) || 0;
    const totalReward:number = Number(ethers.utils.formatUnits(await contract.initreward())) || 0;
    const apy = Number((await this.getAPY2("YNC_LP_REWARD_POOL",erc20Token))) || 0;
    // const apy = Number(await this.getAPY("YNC_LP_REWARD_POOL",erc20Token)) || 0;
    const tokenBalance:BigNumber = await erc20Token.balanceOf(this.myAccount);
    const myBalance = getDisplayBalance(tokenBalance, decimal,4);
    const startTime = parseInt((await contract.starttime()).toString());
    const durationTime = parseInt((await contract.DURATION()).toString())
    const endTime = startTime+durationTime;
    let timeStatus = TimeStatus.NOT_START;
    if(Date.now()/1000>endTime){
      timeStatus = TimeStatus.FINISHED;
    }else if(Date.now()/1000<endTime && Date.now()/1000>startTime){
      timeStatus = TimeStatus.STARTING;
    }

    return {
      tvl:Number(tvl).toFixed(4),
      totalSupply: Number(getDisplayBalance(totalSupply,decimal)).toFixed(4),
      myDepo: Number(getDisplayBalance(myDepo,decimal)).toFixed(4),
      myDepoOld: Number(getDisplayBalance(myDepoOld,decimal)).toFixed(4),
      earned: Number(getDisplayBalance(earned)).toFixed(4),
      lavaEarned: Number(getDisplayBalance(lavaEarned,decimal)).toFixed(4),
      dailyReward: (dailyReward*86400).toFixed(0),
      totalReward: totalReward.toFixed(0),
      apy:(apy*100).toFixed(2)+'%',
      apr:Math.min(999999, (Math.pow(1+Number(apy)/365, 365)-1)*100).toFixed(2) + '%',
      myBalance:Number(myBalance).toFixed(4),
      timeStatus,
    };
  }
  async getNycLpStat(token:string): Promise<any> {

    const erc20Token = this.externalTokens["NYC_USDT_LP"];
    const contract = this.contracts['NYC_LP_REWARD_POOL'];
    // const contractOld = this.contracts['YNC_LP_REWARD_POOL_Old'];
    const decimal = erc20Token.decimal || 18;
    const midPrice: number = (await this.getYNCPrice()) || 0;
    //const midPrice: number = (await this.getPrice(token)) || 0;
    const totalSupply = (await contract.totalSupply()) || BigNumber.from(0);
    //const tvl = ethers.utils.formatUnits(BigNumber.from(parseInt((midPrice * 10000).toString())).mul(totalSupply).div(10000), erc20Token.decimal);

    const tvl = await this.getTVLPre(erc20Token.address, 'NYC_LP_REWARD_POOL', erc20Token.symbol);
    console.log(tvl,'tvl')
    const myDepo = (await contract.balanceOf(this.myAccount)) || BigNumber.from(0);
    const earned = (await contract.earned(this.myAccount)) || BigNumber.from(0);
    // const earnedOld = (await contractOld.earned(this.myAccount)) || BigNumber.from(0);
    const lavaEarned = (await this.earnedLavaP("NYC_LP_REWARD_POOL")) || BigNumber.from(0);
    console.log(lavaEarned,'lavaEarned')
    const dailyReward:number = Number(ethers.utils.formatUnits(await contract.rewardRate())) || 0;
    const totalReward:number = Number(ethers.utils.formatUnits(await contract.initreward())) || 0;
    const apy = Number((await this.getAPY2Nyc("NYC_LP_REWARD_POOL",erc20Token))) || 0;
    // const apy = Number(await this.getAPY("YNC_LP_REWARD_POOL",erc20Token)) || 0;
    const tokenBalance:BigNumber = await erc20Token.balanceOf(this.myAccount);
    const myBalance = getDisplayBalance(tokenBalance, decimal,4);
    const startTime = parseInt((await contract.starttime()).toString());
    const durationTime = parseInt((await contract.DURATION()).toString())
    const endTime = startTime+durationTime;
    let timeStatus = TimeStatus.NOT_START;
    if(Date.now()/1000>endTime){
      timeStatus = TimeStatus.FINISHED;
    }else if(Date.now()/1000<endTime && Date.now()/1000>startTime){
      timeStatus = TimeStatus.STARTING;
    }
    console.log('++++++++')
    return {
      tvl:Number(tvl).toFixed(4),
      totalSupply: Number(getDisplayBalance(totalSupply,decimal)).toFixed(4),
      myDepo: Number(getDisplayBalance(myDepo,decimal)).toFixed(4),
      earned: Number(getDisplayBalance(earned)).toFixed(4),
      lavaEarned: Number(getDisplayBalance(lavaEarned,decimal)).toFixed(4),
      dailyReward: (dailyReward*86400).toFixed(0),
      totalReward: totalReward.toFixed(0),
      apy:(apy*100).toFixed(2)+'%',
      apr:Math.min(999999, (Math.pow(1+Number(apy)/365, 365)-1)*100).toFixed(2) + '%',
      myBalance:Number(myBalance).toFixed(4),
      timeStatus,
    };
  }
  // 获取鱼卡lp信息
  async getFishLpInfo(color:number): Promise<any> {
    const erc20Token = this.externalTokens["NYC_USDT_LP"];
    const poolName = FishLp[color]+'_NFTRewardPool';
    const contract = this.contracts[poolName];
    const decimal = erc20Token.decimal || 18;
    // const midPrice: number = (await this.getYNCPrice()) || 0;
    //const midPrice: number = (await this.getPrice(token)) || 0;
    const totalSupply = (await contract.totalSupply()) || BigNumber.from(0);
    //const tvl = ethers.utils.formatUnits(BigNumber.from(parseInt((midPrice * 10000).toString())).mul(totalSupply).div(10000), erc20Token.decimal);
    const tvl = await this.getTVLPre(erc20Token.address, poolName, erc20Token.symbol);
    const myDepo = (await contract.balanceOf(this.myAccount)) || BigNumber.from(0);
    const earned = (await contract.earned(this.myAccount)) || BigNumber.from(0);
    // const earnedOld = (await contractOld.earned(this.myAccount)) || BigNumber.from(0);
    const lavaEarned = (await this.earnedLavaP(poolName)) || BigNumber.from(0);
    const dailyReward:number = Number(ethers.utils.formatUnits(await contract.rewardRate())) || 0;
    const totalReward:number = Number(ethers.utils.formatUnits(await contract.initreward())) || 0;
    const apy = Number((await this.getAPY2Nyc(poolName,erc20Token))) || 0;
    // const apy = Number(await this.getAPY("YNC_LP_REWARD_POOL",erc20Token)) || 0;
    const tokenBalance:BigNumber = await erc20Token.balanceOf(this.myAccount);
    const myBalance = getDisplayBalance(tokenBalance, decimal,4);
    const startTime = parseInt((await contract.starttime()).toString());
    const durationTime = parseInt((await contract.DURATION()).toString())
    const endTime = startTime+durationTime;
    let timeStatus = TimeStatus.NOT_START;
    if(Date.now()/1000>endTime){
      timeStatus = TimeStatus.FINISHED;
    }else if(Date.now()/1000<endTime && Date.now()/1000>startTime){
      timeStatus = TimeStatus.STARTING;
    }

    return {
      tvl:Number(tvl).toFixed(4),
      totalSupply: Number(getDisplayBalance(totalSupply,decimal)).toFixed(4),
      myDepo: Number(getDisplayBalance(myDepo,decimal)).toFixed(4),
      earned: Number(getDisplayBalance(earned)).toFixed(4),
      lavaEarned: Number(getDisplayBalance(lavaEarned,decimal)).toFixed(4),
      dailyReward: (dailyReward*86400).toFixed(0),
      totalReward: totalReward.toFixed(0),
      apy:(apy*100).toFixed(2)+'%',
      apr:Math.min(999999, (Math.pow(1+Number(apy)/365, 365)-1)*100).toFixed(2) + '%',
      myBalance:Number(myBalance).toFixed(4),
      timeStatus,
      addr:contract.address
    };
  }
  async getNYCPrice(){
    let nyc:BigNumber = (await this.NYC.balanceOf(this.NYC_USDT_LP.address)) || BigNumber.from(0);
    let usdt:BigNumber = (await this.externalTokens["USDT"].balanceOf(this.NYC_USDT_LP.address)) || BigNumber.from(0);
    return Number(ethers.utils.formatUnits(usdt))/Number(ethers.utils.formatUnits(nyc));
  }
  async getYNCPrice(){
    let ync:BigNumber = (await this.YNC.balanceOf(this.YNC_USDT_LP.address)) || BigNumber.from(0);
    let usdt:BigNumber = (await this.externalTokens["USDT"].balanceOf(this.YNC_USDT_LP.address)) || BigNumber.from(0);
    return Number(ethers.utils.formatUnits(usdt))/Number(ethers.utils.formatUnits(ync));
  }
  async getCashStatFromUniswapSHT(): Promise<TokenStat> {
    const supply = await this.sHT.displayedTotalSupply();
    const priceSHT = await this.getTokenPriceFromUniswapPair(this.sHT, this.externalTokens['wHT']);
    return {
      priceInDAI: (Number(priceSHT) * Number(await this.getPrice('wHT'))).toFixed(2),
      priceSp: priceSHT,
      totalSupply: supply,
    };
  }

  async getSNEOStatFromUniswap(): Promise<TokenStat> {
    const supply = await this.externalTokens['sNEO'].displayedTotalSupply();
    const priceSNEO = await this.getTokenPriceFromUniswapPair(this.externalTokens['sNEO'], this.externalTokens['pNEO']);
    return {
      priceInDAI: (Number(priceSNEO) * Number(await this.getPrice('pNEO'))).toFixed(2),
      priceSp: priceSNEO,
      totalSupply: supply,
    };
  }

  // sFund
  async getsFundUsdtFunc(): Promise<TokenStat> {
    const supply = await this.sFUND_USDT.displayedBalanceOf(this.config.externalTokens.Fund[0]);
    const supplyWHT = await this.sFUND_WHT.displayedBalanceOf(this.config.externalTokens.Fund[0]);
    const supplyPNEO = await this.sFUND_PNEO.displayedBalanceOf(this.config.externalTokens.Fund[0]);
    return {
      priceInDAI: String(Number(supply).toFixed(2)),
      totalSupply: String(Number(supplyWHT).toFixed(2)),
      sNeoSupply: String(Number(supplyPNEO).toFixed(2)),
    };
  }

  // sFilda
  async getLiquidityOracle(group: string): Promise<TokenStat> {
    const contact = this.contracts[config.plane[group].lpOracle];
    let priceSP = '0';
    let priceInDAI = '0';
    let supply = '0';
    if (config.plane[group].bankStartAt && Date.now() >= config.plane[group].bankStartAt.getTime()) {
      priceSP = await this.getTokenPriceFromUniswapPair(this.externalTokens['s' + group.toUpperCase()], this.externalTokens[group.toUpperCase()]);
      priceInDAI = (Number(priceSP) * Number(await this.getPrice(group.toUpperCase()))).toFixed(2);
      supply = await this.externalTokens['s' + group.toUpperCase()].displayedTotalSupply();
    }
    const tvl = contact ? ethers.utils.formatUnits(await contact.tvl(), contact.decimal) : '0';
    return {
      priceInDAI: priceInDAI,
      priceSp: priceSP,
      totalSupply: Number(supply).toFixed(2),
      tvl: Number(tvl).toFixed(2),
    };
  }

  async getLiquidityOracleTVLine(group: string): Promise<boolean> {
    if (!group) {
      return false;
    }
    const contact = this.contracts['s' + group.toUpperCase() + '_QPool'];
    const price = 0;
    return contact ? await contact.tvlLine() : false;
  }

  /**
   * @returns Estimated Super Nova (sCASH) price data,
   * calculated by 1-day Time-Weight Averaged Price (TWAP).
   */
  // async getCashStatInEstimatedTWAP(): Promise<TokenStat> {
  //   const { Oracle } = this.contracts;

  //   // estimate current TWAP price
  //   const cumulativePrice: BigNumber = await this.bacDai.price0CumulativeLast();
  //   const cumulativePriceLast = await Oracle.price0CumulativeLast();
  //   const elapsedSec = Math.floor(Date.now() / 1000 - (await Oracle.blockTimestampLast()));

  //   const denominator112 = BigNumber.from(2).pow(112);
  //   const denominator1e18 = BigNumber.from(10).pow(18);
  //   const cashPriceTWAP = cumulativePrice
  //     .sub(cumulativePriceLast)
  //     .mul(denominator1e18)
  //     .div(elapsedSec)
  //     .div(denominator112);

  //   const totalSupply = await this.sCASH.displayedTotalSupply();
  //   return {
  //     priceInDAI: getDisplayBalance(cashPriceTWAP),
  //     totalSupply,
  //   };
  // }


  async getCashStatInEstimatedTWAP(): Promise<TokenStat> {
    // const { SeigniorageOracle } = this.contracts;
    //console.log('getCashStatInEstimatedTWAP', config.group + ' begin');
    if (!config.plane[config.group].oracle) {
      return {
        priceInDAI: '0',
        totalSupply: '0',
      };
    }
    let expectedPrice = await this.contracts[config.plane[config.group].oracle].expectedPrice(
      this.contracts['s' + config.group.toUpperCase()].address,
      ethers.utils.parseEther('1'),
    );
    console.log('getCashStatInEstimatedTWAP', this.contracts[config.plane[config.group].oracle]);
    const supply = await this.sCASH.displayedTotalSupply();
    if (config.group == 'neo' || config.group == 'nuls') {
      expectedPrice = expectedPrice.mul(Math.pow(10, 10));
    }
    return {
      priceInDAI: getDisplayBalance(expectedPrice),
      totalSupply: supply,
    };
  }

  async getCashPriceInLastTWAP(): Promise<BigNumber> {
    const { Treasury_sCASH } = this.contracts;
    return Treasury_sCASH.getSeigniorageOraclePrice();
  }

  async getShareStat(): Promise<TokenStat> {
    let total = Number(await this.SHARE.displayedTotalSupply());
    console.log('total', total);
    let balance = 0;
    const names = ['sCASH_USDT_lp_pool', 'sCASH_HUSD_lp_pool', 'SHARE_USDT_lp_pool', 'SHARE_HUSD_lp_pool', 'sHT_wHT_lp_pool', 'sHT_USDT_lp_pool', 'sHT_sCASH_lp_pool', 'SHARE_wHT_lp_pool', 'sNEO_pNEO_lp_pool', 'sNEO_USDT_lp_pool', 'sNEO_sCASH_lp_pool', 'SHARE_pNEO_lp_pool', 'sFILDA_FILDA_qlp2_pool', 'FILDA_sHT_qlp2_pool', 'SHARE_FILDA_qlp2_pool', 'sNULS_NULS_qlp2_pool', 'sCASH_NULS_qlp2_pool', 'SHARE_NULS_qlp2_pool', 'LavaPool_SHARE'];
    for(let item of names) {
      balance += Number(await this.SHARE.displayedBalanceOf(this.contracts[item].address));
    }
    return {
      priceInDAI: await this.getTokenPriceFromUniswap(this.SHARE),
      totalSupply: (total - balance).toFixed(2),
    };
  }

  async getTokenPriceFromUniswap(tokenContract: ERC20): Promise<string> {
    const key = tokenContract.symbol + 'pricehusd';
    if (getCache(key)) {
      //return getCache(key);
    }

    await this.provider.ready;
    const { chainId } = this.config;
    const { HUSD } = this.config.externalTokens;
    const dai = new Token(chainId, HUSD[0], 8);
    const token = new Token(chainId, tokenContract.address, tokenContract.decimal);
    try {
      const daiToToken = await Fetcher.fetchPairData(dai, token, this.provider);
      const priceInDAI = new Route([daiToToken], token);
      setCache(key, priceInDAI.midPrice.toSignificant(3));
      console.log('price ' + tokenContract.symbol, priceInDAI.midPrice.toSignificant(3));
      return priceInDAI.midPrice.toSignificant(3);
    } catch (err) {
      console.error(`Failed to fetch token price of ${tokenContract.symbol}: ${err}`);
    }
  }

  async getTokenPriceFromUniswapPair(tokenContract: ERC20, unitTokenContract: ERC20): Promise<string> {
    const key = tokenContract.symbol + 'pricewht';
    if (getCache(key)) {
      //return getCache(key);
    }

    await this.provider.ready;
    const { chainId } = this.config;
    const { wHT } = this.config.externalTokens;

    const dai = new Token(chainId, unitTokenContract.address, unitTokenContract.decimal);
    const token = new Token(chainId, tokenContract.address, tokenContract.decimal);
    try {
      const daiToToken = await Fetcher.fetchPairData(dai, token, this.provider);
      const priceInDAI = new Route([daiToToken], token);
      setCache(key, priceInDAI.midPrice.toSignificant(3));
      return priceInDAI.midPrice.toSignificant(3);
    } catch (err) {
      console.error(`Failed to fetch token price of ${tokenContract.symbol}: ${err}`);
    }
  }

  async earnedFromBank(poolName: ContractName, account = this.myAccount): Promise<BigNumber> {
    const pool = this.contracts[poolName];
    try {
      if (config.plane[config.group].lp2 && poolName.includes('qlp2')) {
        const tvl = await pool.getTvl();
        console.log('earned', tvl);
        const minTVL = await pool.minTVL();
        console.log('earned', minTVL);
        const earned = await pool.earned(account);
        console.log('earned', earned);
        return earned;//.mul(tvl).div(minTVL);
      } else {
        return await pool.earned(account);
      }
    } catch (err) {
      console.error(`Failed to call earned() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }
  async earnedFromBankContract(pool: Contract, account = this.myAccount): Promise<BigNumber> {
    try {
        return await pool.earned(account);
    } catch (err) {
      console.error(`Failed to call earned() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }

  async earnedFildaP(poolName: ContractName, account = this.myAccount): Promise<BigNumber> {
    const pool = this.contracts[poolName];
    try {
      return await pool.earnedFildaP(account);
    } catch (err) {
      console.error(`Failed to call earnedFildaP() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }
// 获取 lava收益
  async earnedLavaP(poolName: ContractName, account = this.myAccount): Promise<BigNumber> {
    const pool = this.contracts[poolName];
    try {
      return await pool.earnedLavaP(account);
    } catch (err) {
      console.error(`Failed to call earnedLavaP() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }

  async earnedVSHARE(account = this.myAccount): Promise<BigNumber> {
    const pool = this.contracts['shareSplit'];
    try {
      return await pool.earnedV(account);
    } catch (err) {
      console.error(`Failed to call earnedFildaP() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }

  async earnedSSHARE(account = this.myAccount): Promise<BigNumber> {
    const pool = this.contracts['shareSplit'];
    try {
      return await pool.earnedS(account);
    } catch (err) {
      console.error(`Failed to call earnedFildaP() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }

  async getVoteList(): Promise<number[]> {
    const pool = this.contracts['proposal'];
    try {
      const total = await pool.getVoteItemCount();
      const max = Number(ethers.utils.formatUnits(total, 0));
      const result = [];
      for(let i=0;i<max;i++) {
        const vote = await pool.totalVotes(i);
        const v = Number(ethers.utils.formatUnits(vote, 0));
        result.push(v);
      }
      return result;
    } catch (err) {
      console.error(`Failed to call earnedFildaP() on pool ${pool.address}: ${err.stack}`);
      return [];
    }
  }

  async stakedBalanceOnBank(
    poolName: ContractName,
    account = this.myAccount,
  ): Promise<BigNumber> {
    const pool = this.contracts[poolName];
    try {
      return await pool.balanceOf(account);
    } catch (err) {
      console.error(`Failed to call balanceOf() on pool ${pool.address}: ${err.stack}`);
      return BigNumber.from(0);
    }
  }

  /**
   * Deposits token to given pool.
   * @param poolName A name of pool contract.
   * @param amount Number of tokens with decimals applied. (e.g. 1.45 HUSD * 10^18)
   * @returns {string} Transaction hash
   */
  async stake(poolName: ContractName, amount: BigNumber): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    console.log(pool,'pool')
    const gas = await pool.estimateGas.stake(amount);
    return await pool.stake(amount, this.gasOptions(gas));
  }
  async stakeContract(pool:Contract, amount: BigNumber): Promise<TransactionResponse> {
    const gas = await pool.estimateGas.stake(amount);
    return await pool.stake(amount, this.gasOptions(gas));
  }
  async stakeV(poolName: ContractName, amount: BigNumber): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    const gas = await pool.estimateGas.stakeV(amount);
    return await pool.stakeV(amount, this.gasOptions(gas));
  }

  async voted(poolName: ContractName, name: BigNumber): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    console.log('vote', pool);
    const gas = await pool.estimateGas.vote(name);
    return await pool.vote(name, this.gasOptions(gas));
  }

  /**
   * Withdraws token from given pool.
   * @param poolName A name of pool contract.
   * @param amount Number of tokens with decimals applied. (e.g. 1.45 HUSD * 10^18)
   * @returns {string} Transaction hash
   */
  async unstake(poolName: ContractName, amount: BigNumber): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    const gas = await pool.estimateGas.withdraw(amount);
    return await pool.withdraw(amount, this.gasOptions(gas));
  }
  async unstakeContract(pool: Contract, amount: BigNumber): Promise<TransactionResponse> {
    const gas = await pool.estimateGas.withdraw(amount);
    return await pool.withdraw(amount, this.gasOptions(gas));
  }
  /**
   * Transfers earned token reward from given pool to my account.
   */
  async harvest(poolName: ContractName): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    const gas = await pool.estimateGas.getReward();
    return await pool.getReward(this.gasOptions(gas));
  }
  async harvestContract(pool: Contract): Promise<TransactionResponse> {
    const gas = await pool.estimateGas.getReward();
    return await pool.getReward(this.gasOptions(gas));
  }
  async harvestV(): Promise<TransactionResponse> {
    const pool = this.contracts['shareSplit'];
    const gas = await pool.estimateGas.getRewardV();
    return await pool.getRewardV(this.gasOptions(gas));
  }

  async harvestS(): Promise<TransactionResponse> {
    const pool = this.contracts['shareSplit'];
    const gas = await pool.estimateGas.getRewardS();
    return await pool.getRewardS(this.gasOptions(gas));
  }

  async split(poolName: ContractName): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    const gas = await pool.estimateGas.split();
    return await pool.split(this.gasOptions(gas));
  }

  async buyFishCard(poolName: ContractName, idx: BigNumber): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    const gas = await pool.estimateGas.buyFishCard(idx);
    return await pool.buyFishCard(idx, this.gasOptions(gas));
  }

  /**
   * Harvests and withdraws deposited tokens from the pool.
   */
  async exit(poolName: ContractName): Promise<TransactionResponse> {
    const pool = this.contracts[poolName];
    const gas = await pool.estimateGas.exit();
    return await pool.exit(this.gasOptions(gas));
  }

  async fetchBoardroomVersionOfUser(): Promise<string> {
    // const { Boardroom1, Boardroom2 } = this.contracts;
    // const balance1 = await Boardroom1.getShareOf(this.myAccount);
    // if (balance1.gt(0)) {
    //   console.log(
    //     `👀 The user is using Boardroom v1. (Staked ${getDisplayBalance(balance1)} SHARE)`,
    //   );
    //   return 'v1';
    // }
    // const balance2 = await Boardroom2.balanceOf(this.myAccount);
    // if (balance2.gt(0)) {
    //   console.log(
    //     `👀 The user is using Boardroom v2. (Staked ${getDisplayBalance(balance2)} SHARE)`,
    //   );
    //   return 'v2';
    // }
    return 'latest';
  }

  boardroomByVersion(v: boolean): Contract {
    if (v) {
      return this.contracts['LPBoardroom2_s' + this.config.group.toUpperCase()];
    }
    return this.contracts['LPBoardroom_s' + this.config.group.toUpperCase()];
  }

  boardroomByVersion1(v: boolean): Contract {
    if (v) {
      return this.contracts['ShareBoardroom2_s' + this.config.group.toUpperCase()];
    }
    return this.contracts['ShareBoardroom_s' + this.config.group.toUpperCase()];
  }

  currentBoardroom(v: boolean): Contract {
    if (!this.boardroomVersionOfUser) {
      throw new Error('you must unlock the wallet to continue.');
    }
    return this.boardroomByVersion(v);
  }

  currentBoardroom1(v: boolean): Contract {
    if (!this.boardroomVersionOfUser) {
      throw new Error('you must unlock the wallet to continue.');
    }
    return this.boardroomByVersion1(v);
  }

  isOldBoardroomMember(): boolean {
    return this.boardroomVersionOfUser !== 'latest';
  }

  async stakeShareToBoardroom(amount: string, v: boolean): Promise<TransactionResponse> {
    if (this.isOldBoardroomMember()) {
      throw new Error("you're using old Boardroom. please withdraw and deposit the SHARE again.");
    }
    const Boardroom = this.currentBoardroom(v);
    return await Boardroom.stake(decimalToBalance(amount));
  }

  async getStakedSharesOnBoardroom(v: boolean): Promise<BigNumber> {
    const Boardroom = this.currentBoardroom(v);
    if (!Boardroom) {
      return BigNumber.from(0);
    }
    return await Boardroom.balanceOf(this.myAccount);
  }

  async getEarningsOnBoardroom(v: boolean): Promise<BigNumber> {
    const Boardroom = this.currentBoardroom(v);
    if (!Boardroom) {
      return BigNumber.from(0);
    }
    return await Boardroom.earned(this.myAccount);
  }

  async withdrawShareFromBoardroom(amount: string, v: boolean): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom(v);
    return await Boardroom.withdraw(decimalToBalance(amount));
  }

  async harvestCashFromBoardroom(v: boolean): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom(v);
    return await Boardroom.claimReward();
  }

  async exitFromBoardroom(v: boolean): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom(v);
    return await Boardroom.exit();
  }

  async getLastStakeTime(v: boolean): Promise<string> {
    const Boardroom = this.currentBoardroom(v);
    if (!Boardroom || !Boardroom.getLastStakeTime) {
      return '0';
    }
    return ethers.utils.formatUnits(await Boardroom.getLastStakeTime(), 0);
  }

  // Boardroom 复制版本

  async stakeShareToBoardroom1(amount: string): Promise<TransactionResponse> {
    if (this.isOldBoardroomMember()) {
      throw new Error("you're using old Boardroom. please withdraw and deposit the SHARE again.");
    }
    const Boardroom = this.currentBoardroom1(false);
    return await Boardroom.stake(decimalToBalance(amount));
  }

  async stake0ToBoardroom1(amount: string): Promise<TransactionResponse> {
    if (this.isOldBoardroomMember()) {
      throw new Error("you're using old Boardroom. please withdraw and deposit the SHARE again.");
    }
    const Boardroom = this.currentBoardroom1(true);
    return await Boardroom.stake0(decimalToBalance(amount));
  }

  async stake1ToBoardroom1(amount: string): Promise<TransactionResponse> {
    if (this.isOldBoardroomMember()) {
      throw new Error("you're using old Boardroom. please withdraw and deposit the SHARE again.");
    }
    const Boardroom = this.currentBoardroom1(true);
    return await Boardroom.stake1(decimalToBalance(amount));
  }

  async getStakedSharesOnBoardroom1(): Promise<BigNumber> {
    const Boardroom = this.currentBoardroom1(false);
    if (!Boardroom) {
      return BigNumber.from(0);
    }
    return await Boardroom.balanceOf(this.myAccount);
  }

  async getBalanceOf0OnBoardroom1(): Promise<BigNumber> {
    const Boardroom = this.currentBoardroom1(true);
    if (!Boardroom) {
      return BigNumber.from(0);
    }
    return await Boardroom.balanceOf0(this.myAccount);
  }

  async getBalanceOf1OnBoardroom1(): Promise<BigNumber> {
    const Boardroom = this.currentBoardroom1(true);
    if (!Boardroom) {
      return BigNumber.from(0);
    }
    return await Boardroom.balanceOf1(this.myAccount);
  }

  async getEarningsOnBoardroom1(v: boolean): Promise<BigNumber> {
    const Boardroom = this.currentBoardroom1(v);
    return await Boardroom.earned(this.myAccount);
  }

  async withdrawShareFromBoardroom1(amount: string): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom1(false);
    return await Boardroom.withdraw(decimalToBalance(amount));
  }

  async withdraw0FromBoardroom1(amount: string): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom1(true);
    return await Boardroom.withdraw0(decimalToBalance(amount));
  }

  async withdraw1FromBoardroom1(amount: string): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom1(true);
    return await Boardroom.withdraw1(decimalToBalance(amount));
  }

  async harvestCashFromBoardroom1(v: boolean): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom1(v);
    return await Boardroom.claimReward();
  }

  async exitFromBoardroom1(v: boolean): Promise<TransactionResponse> {
    const Boardroom = this.currentBoardroom1(v);
    return await Boardroom.exit();
  }
  async getLastStakeTime1(v: boolean): Promise<string> {
    const Boardroom = this.currentBoardroom1(v);
    if (!Boardroom || !Boardroom.getLastStakeTime) {
      return '0';
    }
    return ethers.utils.formatUnits(await Boardroom.getLastStakeTime(), 0);
  }

  async getAddition(): Promise<number> {
    const stat = await this.getCashStatInEstimatedTWAP();
    const expansionSpeed = Math.min(2, Number(stat.priceInDAI));
    const totalSupply = await this.externalTokens['s' + this.config.group.toUpperCase()].displayedTotalSupply();
    return Number(totalSupply) * (expansionSpeed - 1) * 0.85;
  }

  async getLPBonusRatio(): Promise<number> {
    const addition = await this.getAddition();
    console.log('getLPBonusRatio addition', addition);
    const planePrice = await this.getPlanePrice();
    console.log('getLPBonusRatio planePrice', planePrice);
    const balance = await this.SHARE.displayedBalanceOf(this.externalTokens['s' + this.config.group.toUpperCase() + '_SHARE_LP'].address);
    console.log('getLPBonusRatio balance', balance);
    const sharePrice = await this.getTokenPriceFromUniswap(this.SHARE);
    console.log('getLPBonusRatio sharePrice', sharePrice);
    const ratio = (Number(balance) == 0 ? 0 : addition * Number(planePrice) * 0.85 / (Number(balance) * 2 * Number(sharePrice)));
      console.log('getLPBonusRatio', ratio);
    return Math.max(ratio, 0);
  }

  async getShareBonusRatio(): Promise<number> {
    const addition = await this.getAddition();
    const planePrice = await this.getPlanePrice();
    console.log('getLPBonusRatio planePrice', planePrice);
    let balance = '0';
    if (this.config.plane[this.config.group].lp) {
      balance = (Number(await this.SHARE.displayedBalanceOf(this.contracts['ShareBoardroom2_s' + this.config.group.toUpperCase()].address)) + Number(await this.externalTokens['sSHARE'].displayedBalanceOf(this.contracts['ShareBoardroom2_s' + this.config.group.toUpperCase()].address))).toFixed(2);
    } else {
      balance = await this.SHARE.displayedBalanceOf(this.contracts['ShareBoardroom_s' + this.config.group.toUpperCase()].address);
    }
    console.log('getLPBonusRatio balance', balance);
    const sharePrice = await this.getTokenPriceFromUniswap(this.SHARE);
    console.log('getLPBonusRatio sharePrice', sharePrice);
    return Math.max(Number(balance) == 0 ? 0 : addition * Number(planePrice) * 0.15 / (Number(balance) * Number(sharePrice)), 0);
  }



  // 结束Boardroom

  async getTreasuryNextAllocationTime(): Promise<TreasuryAllocationTime> {
    const { Treasury_sCASH } = this.contracts;
    const nextEpochTimestamp: BigNumber = await Treasury_sCASH.nextEpochPoint();
    const period: BigNumber = await Treasury_sCASH.getPeriod();

    const nextAllocation = new Date(nextEpochTimestamp.mul(1000).toNumber());
    const prevAllocation = new Date(nextAllocation.getTime() - period.toNumber() * 1000);
    return { prevAllocation, nextAllocation };
  }

  async getPrice(symbol: string): Promise<number> {
    if (this.priceConfigs[symbol]) {
      return this.priceConfigs[symbol];
    } else {
      if (this.fConfigs[symbol]) {
        const token = new ERC20(this.config.externalTokens[this.fConfigs[symbol]][0], this.provider, this.fConfigs[symbol], this.config.externalTokens[this.fConfigs[symbol]][1]);
        this.priceConfigs[symbol] = Number(await this.getTokenPriceFromUniswap(token)) / 45;
        return this.priceConfigs[symbol];
      } else {
        const token = new ERC20(this.config.externalTokens[symbol][0], this.provider, symbol, this.config.externalTokens[symbol][1]);
        if (this.wHTConfigs.indexOf(symbol) >= 0) {
          this.priceConfigs[symbol] = Number(await this.getTokenPriceFromUniswapPair(token, this.externalTokens['wHT'])) * Number(await this.getPrice('wHT'));
          return this.priceConfigs[symbol];
        } else if (this.NULSConfigs.indexOf(symbol) >= 0) {
          this.priceConfigs[symbol] = Number(await this.getTokenPriceFromUniswapPair(token, this.externalTokens['NULS'])) * Number(await this.getPrice('NULS'));
          return this.priceConfigs[symbol];
        } else if (this.USDTConfigs.indexOf(symbol) >= 0) {
          this.priceConfigs[symbol] = Number(await this.getTokenPriceFromUniswapPair(token, this.externalTokens['USDT']));
          return this.priceConfigs[symbol];
        } else {
          this.priceConfigs[symbol] = Number(await this.getTokenPriceFromUniswap(token));
          if (symbol == 'SHARE') {
            const lavaSHARE = Number(await this.externalTokens.USDT.displayedBalanceOf(this.externalTokens.SHARE_USDT_LAVA_LP.address)) / Number(await this.externalTokens.SHARE.displayedBalanceOf(this.externalTokens.SHARE_USDT_LAVA_LP.address));
            console.log('lavaSHARE', lavaSHARE);
            this.priceConfigs[symbol] = (this.priceConfigs[symbol] + lavaSHARE) / 2;
          }
          return this.priceConfigs[symbol];
        }
      }
    }
  }

  async getTVL(pool: string, token: ERC20): Promise<string> {
    const key = pool + 'tvl' + token.symbol;
    if (getCache(key)) {
      return getCache(key);
    }

    // this.linshiBJ = new ERC20(this.config.externalTokens[token.symbol][0], this.provider, token.symbol);

    // try{
      let midPrice: number = await this.getPrice(token.symbol);
      let midPrices: string;
      // if (token.symbol == 'USDT' || token.symbol == 'HUSD') {
      //   midPrices = '1';
      // } else {
      //   midPrices = await this.getTokenPriceFromUniswap(token);
      // }

      let ymidPrices: number;
      if (midPrices) {
        ymidPrices = Number(midPrices);
      } else {
        ymidPrices = Number(midPrice);
      }
      const totalSupply: BigNumber = await this.contracts[pool].totalSupply();
      console.log('externalTokens', token.symbol, midPrice, ethers.utils.formatUnits(totalSupply, token.decimal), '++++',  ymidPrices);

      if(ymidPrices && totalSupply){
        return ethers.utils.formatUnits(BigNumber.from(parseInt((ymidPrices * 10000).toString())).mul(totalSupply).div(10000), token.decimal);
      }
      setCache(key, BigNumber.from(0).toString());
      return BigNumber.from(0).toString();
    // }catch (err) {
    //   return BigNumber.from(0).toString();
    // }
  }

  async getPlanePrice(): Promise<string> {
    if (config.group == 'cash') {
      return await this.getTokenPriceFromUniswap(this.sCASH);
    } else if (config.group == 'ht') {
      const sHtPrice = await this.getTokenPriceFromUniswapPair(this.sHT, this.externalTokens['wHT']);
      return (Number(await this.getPrice('wHT')) * Number(sHtPrice)).toString();
    } else if (config.group == 'neo') {
      const sHtPrice = await this.getTokenPriceFromUniswapPair(this.externalTokens['sNEO'], this.externalTokens['pNEO']);
      return (Number(await this.getPrice('pNEO')) * Number(sHtPrice)).toString();
    } else {
      const sHtPrice = await this.getTokenPriceFromUniswapPair(this.externalTokens['s' + this.config.group.toUpperCase()], this.externalTokens[this.config.spConfigs['s' + this.config.group.toUpperCase()]]);
      return (Number(await this.getPrice(this.config.spConfigs['s' + this.config.group.toUpperCase()])) * Number(sHtPrice)).toString();
      //return (await this.getPrice('s' + config.group.toUpperCase())).toFixed(2);
    }
  }

  async getAPY(pool: string, token: ERC20): Promise<string> {
    const key = pool + 'apy' + token.symbol;
    if (getCache(key)) {
      return getCache(key);
    }
    // try{
      //const duration = Number(ethers.utils.formatUnits(await this.contracts[pool].duration()));
      //console.log('rewardduration', duration);
      const reward = Number(ethers.utils.formatUnits(await this.contracts[pool].rewardRate())) * 5*24*3600;
      //const reward = 100;
      const scashPrice: string = await this.getPlanePrice();
      console.log('reward', scashPrice);

      const tvl = await this.getTVL(pool, token);
      if(BigNumber.from(parseInt(tvl)) <= BigNumber.from(0)){
        return '0';
      }
      // let apy = reward.div(5).mul(BigNumber.from(scashPrice)).mul(365).div(tvl);
      let apy = reward / 5 * parseFloat(scashPrice) * 365 / parseFloat(tvl);
      setCache(key, apy.toString());
      return apy.toString();

    // }catch (err) {
    //   return BigNumber.from(0).toString();
    // }
  }
  async getYNCApy(pool: string, token: ERC20,tvl:string,v2:boolean): Promise<string> {
    const reward = Number(ethers.utils.formatUnits(await this.contracts[pool].rewardRate())) * 5*24*3600;

    //const reward = 100;
    const price: number = await (v2?this.getNYCPrice():this.getYNCPrice());
    if(BigNumber.from(parseInt(tvl)) <= BigNumber.from(0)){
      return '0';
    }
    // let apy = reward.div(5).mul(BigNumber.from(scashPrice)).mul(365).div(tvl);
    let apy = reward / 5 * price * 365 / parseFloat(tvl);
    console.log('apy ' + reward + ' ' + price + ' ' + tvl);

    return apy.toString();

    // }catch (err) {
    //   return BigNumber.from(0).toString();
    // }
  }
  async getAPYContract(contract: Contract, token: ERC20,tvl:number): Promise<number> {

    const reward = Number(ethers.utils.formatUnits(await contract.rewardRate())) * 24*3600;
    // yncprice
    const scashPrice: string = await this.getPlanePrice();

    if(tvl <=0){
      return 0;
    }
    let apy = reward * parseFloat(scashPrice) * 365 / tvl;
    return apy;
  }

  async getTVL2(pool: string): Promise<string> {
    const key = pool + 'tvl2';
    if (getCache(key)) {
      //return getCache(key);
    }
    // console.log(pool,"pool========");
    const arrayHUSD = ['0x29471983b759Ccb802f486244B26A7c7dce8b7B5',
                      '0xb1188f0bb3eb9a49C0bfcFA87238773352C151C4'
    ];
    const arrayWHT = [config.externalTokens.sHT_wHT_LP[0], config.externalTokens.SHARE_wHT_LP[0]];
    const arraySCASH = [config.externalTokens.sHT_sCASH_LP[0], config.externalTokens.sNEO_sCASH_LP[0]];
    const arrayPNEO = [config.externalTokens.sNEO_pNEO_LP[0], config.externalTokens.SHARE_pNEO_LP[0]];
    const arraySFILDA = [config.externalTokens.sHT_Filda_LP[0], config.externalTokens.sFILDA_FILDA_LP[0], config.externalTokens.SHARE_FILDA_LP[0]];
    const arraySCAN = [config.externalTokens.sHT_CAN_LP[0]];
    const arraySNULS = [config.externalTokens.sCASH_NULS_LP[0], config.externalTokens.sNULS_NULS_LP[0], config.externalTokens.SHARE_NULS_LP[0]];
    const arraySNEO = [config.externalTokens.sNEO_pFLM_LP[0]];
    const arraySHT = [config.externalTokens.FILDA_sHT_LP[0]];
    const arrayMDX = [config.externalTokens.sHT_MDX_LP[0]];

    let name = 'USDT';
    if(arrayHUSD.indexOf(pool) >= 0){
      name = 'HUSD';
    }
    if (arrayWHT.indexOf(pool) >= 0) {
      name = 'wHT';
    }
    if (arraySCASH.indexOf(pool) >= 0) {
      name = 'sCASH';
    }
    if (arrayPNEO.indexOf(pool) >= 0) {
      name = 'pNEO';
    }
    if (arraySFILDA.indexOf(pool) >= 0) {
      name = 'Filda';
    }
    if (arraySCAN.indexOf(pool) >= 0) {
      name = 'CAN';
    }
    if (arraySNULS.indexOf(pool) >= 0) {
      name = 'NULS';
    }
    if (arraySNEO.indexOf(pool) >= 0) {
      name = 'sNEO';
    }
    if (arraySHT.indexOf(pool) >= 0) {
      name = 'sHT';
    }
    if (arrayMDX.indexOf(pool) >= 0) {
      name = 'MDX';
    }

    const token = this.externalTokens[name];
    let total: BigNumber = await token.balanceOf(pool);

    const price = await this.getPrice(name);
    console.log('tvl2 ' + pool + ' ' + price + ' ' + ethers.utils.formatUnits(total.mul(2).toString(), token.decimal));
    setCache(key, (Number(ethers.utils.formatUnits(total.mul(2).toString(), token.decimal)) * price).toString());
    return (Number(ethers.utils.formatUnits(total.mul(2).toString(), token.decimal)) * price).toString();
  }

  async getAPY2(pool: string, token: ERC20): Promise<string> {
    const key = token.symbol + 'apy2';
    if (getCache(key)) {
      return getCache(key);
    }
    let name = 'sCASH';

    const reward = Number(ethers.utils.formatUnits(await this.contracts[pool].rewardRate())) * 24*3600;

      const sharePrice = await this.getYNCPrice();

      //const tvl = await this.getTVL2(token.address);
      const tvl = await this.getTVLPre(token.address, pool, token.symbol);
      if(parseFloat(tvl) <= 0){
        return '0';
      }
      // let apy = reward.div(5).mul(BigNumber.from(scashPrice)).mul(365).div(tvl);
      console.log('tvl', reward + ' ' + sharePrice  + ' ' + tvl + ' ' + token.address);
      //console.log('tvl', tvl);
      let apy = reward * sharePrice * 365 / parseFloat(tvl);
      /*
      if (config.plane[config.group].lp) {
        const contact = this.contracts[config.plane[config.group].lpOracle];
        const lpTvl = contact ? ethers.utils.formatUnits(await contact.tvl(), contact.decimal) : '0';
        apy = apy * Math.min(config.plane[config.group].lp, Number(lpTvl)) / config.plane[config.group].lp;
      }
      */
      setCache(key, apy.toString());
      return apy.toString();

    // }catch (err) {
    //   return BigNumber.from(0).toString();
    // }
  }
  async getAPY2Nyc(pool: string, token: ERC20): Promise<string> {
    const key = token.symbol+pool + 'apy2';
    console.log(pool,token,key,'+++++++')
    if (getCache(key)) {
      return getCache(key);
    }
    let name = 'sCASH';

    const reward = Number(ethers.utils.formatUnits(await this.contracts[pool].rewardRate())) * 24*3600;

      const sharePrice = await this.getNYCPrice();

      //const tvl = await this.getTVL2(token.address);
      const tvl = await this.getTVLPre(token.address, pool, token.symbol);
      if(parseFloat(tvl) <= 0){
        return '0';
      }
      // let apy = reward.div(5).mul(BigNumber.from(scashPrice)).mul(365).div(tvl);
      console.log('tvl', reward + ' ' + sharePrice  + ' ' + tvl + ' ' + token.address);
      //console.log('tvl', tvl);
      let apy = reward * sharePrice * 365 / parseFloat(tvl);
      /*
      if (config.plane[config.group].lp) {
        const contact = this.contracts[config.plane[config.group].lpOracle];
        const lpTvl = contact ? ethers.utils.formatUnits(await contact.tvl(), contact.decimal) : '0';
        apy = apy * Math.min(config.plane[config.group].lp, Number(lpTvl)) / config.plane[config.group].lp;
      }
      */
      setCache(key, apy.toString());
      return apy.toString();

    // }catch (err) {
    //   return BigNumber.from(0).toString();
    // }
  }
  async getTVLPre(pool: string, contract: string, lpName: string): Promise<string> {
    console.log('getTVLPre', contract);
    console.log('getTVLPre', lpName);
    const tvl = await this.getTVL2(pool);
    console.log('getTVLPre tvl ' + lpName, tvl);
    const total = ethers.utils.formatUnits(await this.externalTokens[lpName].totalSupply(), this.externalTokens[lpName].decimal);
    console.log('getTVLPre total ' + lpName, total);
    //const balance = await this.externalTokens[lpName].displayedBalanceOf(this.contracts[contract].address);
    const balance = ethers.utils.formatUnits(await this.contracts[contract].totalSupply(), this.externalTokens[lpName].decimal);
    console.log('getTVLPre balance ' + lpName, balance);
    return (Number(tvl) * Number(balance) / Number(total)).toFixed(2);
  }
  async getBlackholeSwap(contract: string): Promise<string> {
    if (contract.includes('PegPool')) {
      return (Number(await this.externalTokens[this.config.spConfigs['s' + this.config.group.toUpperCase()]].displayedBalanceOf(this.config.externalTokens.Fund[0])) / 19).toString();
    } else if (contract.includes('CashPool')) {
      return (Number(await this.externalTokens['s' + config.group.toUpperCase()].displayedTotalSupply()) * 0.05 * 0.05).toString();
    } else {
      return '100';
    }
  }

  async getPoolLastAmount(contract: string): Promise<string> {
    if (contract.includes('PegPool')) {
      return ethers.utils.formatUnits(await this.contracts['Treasury3_s' + this.config.group.toUpperCase()].pegPoolLastAmount(), this.externalTokens[this.config.spConfigs['s' + this.config.group.toUpperCase()]].decimal);
    } else if (contract.includes('CashPool')) {
      return ethers.utils.formatUnits(await this.contracts['Treasury3_s' + this.config.group.toUpperCase()].cashPoolLastAmount());
    } else {
      return ethers.utils.formatUnits(await this.contracts['Treasury3_s' + this.config.group.toUpperCase()].sharePoolLastAmount());
    }
  }

 getScashBalance=(address:string):Promise<string>=> {
    return this.sCASH.displayedBalanceOf(address);
  }
  getShareBalance=(address:string):Promise<string>=>{
    return this.SHARE.displayedBalanceOf(address);
  }
  async getUsdtBalance(address:string):Promise<string> {
    const usdt = this.externalTokens['USDT'];
    let total: BigNumber = await usdt.balanceOf(address);
    return ethers.utils.formatUnits(total.mul(2).toString(), usdt.decimal);
  }

  async getAddressBalanceByToken(address: string, token: ERC20): Promise<string> {
    const balance: BigNumber = await this.externalTokens[token.symbol].balanceOf(address);
    return ethers.utils.formatUnits(balance.toString(), token.decimal);
  }

  async post(param: string) {
    const completeUrl = 'https://ttyy.woaiqsh.com/fishapi/';
    const response = await fetch(completeUrl, {
        method: 'POST',
        //credentials: 'include',
        //mode: 'no-cors',
        headers: {
            'Accept': "application/json, text/plain, */*",
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: 'cmd=user_signup&country=86&invitation_code=123456&lang=zh&nc_sessionid=01MwBaZGJV0F4SDerANby-Hto90GybSNEMR7OC7ylQRAnXd56xdyd43HnmHYLkYVrtbTYgUKG_FfMOOoJ_2dOV2b3Sz353xHtjJcnEr-RKNUGUuD5ysCXKa_tPMpgpAbMTfreVBFiUMyGjrbPO7PLSgw&nc_sig=05XqrtZ0EaFgmmqIQes-s-CNiK-Rb15kHVwyR8IPeOhDrU7uSxjcm5PjYxh9FG3GeKXsoCI4CeKL7YOP8iFCcAfK4HJLbivGMuoPAn3yLhChUHwNcqFe4fShosY2Av9SDbt0QgNiQLQvO9AmYegp37HETV6QBd-pUYMZbgK-tMhPHKgv-rrskp260H2xh3ws7y8rU4PZZTaHshxaLry-yXn-y-xUMJoZJSud_d09fvwwiaqoZg7bvhyN5mBz8GrbS1FE169mBBIlBhyFcFPcbZYYGC_CoCvtpZohKKIpEjvXFPWKimTm4R4fTT8x1Q0JkrQIKMzmkgz3nEw6ICJGTHdDF_Gkli9vPCkLHz_qma1fSocISBOgCoVoolldwrNqK3&nc_token=1615458833118:0.6216289898545744&password=d32f7efeaa6db433066894519f96296dd57a1a47fffebaf584060c3f1e0a5189&phone=13811118402&rnd=9673202&sid=&sms_code=1234&ts=1615458865627&ver=1.2.3&sig=07228e6848d69c3011c91fd499bf6a1a5286167d160c2d1a4af4211b8c639a5d'
    });
    return await response.json();
  }
  async getTVLFromBoardroom(): Promise<string> {
    let share = 0;
    if (this.contracts['ShareBoardroom_s' + config.group.toUpperCase()]) {
      share += Number(await this.externalTokens['SHARE'].displayedBalanceOf(this.contracts['ShareBoardroom_s' + config.group.toUpperCase()].address));
    }
      share += Number(await this.externalTokens['SHARE'].displayedBalanceOf(this.contracts['ShareBoardroom2_s' + config.group.toUpperCase()].address));
      //const sShare = await this.externalTokens['sSHARE'].displayedBalanceOf(this.contracts['ShareBoardroom_s' + this.config.group.toUpperCase()].address);
      const lpShare = await this.externalTokens['SHARE'].displayedBalanceOf(this.externalTokens['s' + config.group.toUpperCase() + '_SHARE_LP'].address);
      const lpScash = await this.externalTokens['sCASH'].displayedBalanceOf(this.externalTokens['s' + config.group.toUpperCase() + '_SHARE_LP'].address);
      console.log('tvl', config.group + ' ' + ((Number(share) + Number(lpShare)) * Number(await this.getPrice('SHARE')) + Number(lpScash) * Number(await this.getPrice('sCASH'))));
      return ((Number(share) + Number(lpShare)) * Number(await this.getPrice('SHARE')) + Number(lpScash) * Number(await this.getPrice('sCASH'))).toFixed(2);
  }

  async getTotalTVL(): Promise<string> {
    type dataConfig = {
      totaltvl: number,
      amount: number,
      tvl: {[group: string]: number},
    };
    const data: dataConfig = {'totaltvl': 0, 'amount': 0, 'tvl': {}};
    const groups = ['cash', 'ht', 'neo', 'filda'];
    let total = 0;
    for(var i=0;i<groups.length;i++) {
      let group = groups[i];
      config.group = group;
      const tvl = Number(await this.getTVLFromBoardroom());
      total += tvl;
      data.tvl[group] ? data.tvl[group] += tvl : data.tvl[group] = tvl;
      await delay(500);
    }
    config.group = 'cash';

    for (const bankInfo of Object.values(bankDefinitions)) {
      let tvl = 0;
      if (bankInfo.earnTokenName == 'SHARE') {
        tvl = Number(await this.getTVL2(this.externalTokens[bankInfo.depositTokenName].address));
      } else if (bankInfo.sort == 0) {
        const o = await this.getLiquidityOracle(bankInfo.group);
        tvl = Number(o.tvl);
      } else {
        tvl = Number(await this.getTVL(bankInfo.contract, this.externalTokens[bankInfo.depositTokenName]));
      }
      total += tvl;
      data.tvl[bankInfo.group] ? data.tvl[bankInfo.group] += tvl : data.tvl[bankInfo.group] = tvl;
      await delay(500);
      console.log('tvl', total);
    }
    data.totaltvl = total;
    await this.postData(JSON.stringify(data));
    return total.toFixed(2);
  }
  async postData(data: string) {
    if (process.env.NODE_ENV == "development") {
      const completeUrl = 'https://ttyy.you-fish.com/super/set_json_data';
      const response = await fetch(completeUrl, {
          method: 'POST',
          //credentials: 'include',
          //mode: 'no-cors',
          headers: {
              'Accept': "application/json, text/plain, */*",
              'Content-Type': 'application/json',
          },
          body: data
      });
      return await response;
    }
  }
  async getData() {
    const completeUrl = 'https://ttyy.you-fish.com/super/get_json_data';
    const response = await fetch(completeUrl, {
        method: 'GET',
        //credentials: 'include',
        //mode: 'no-cors',
        headers: {
          'Accept': "application/json, text/plain, */*",
          'Content-Type': 'application/x-www-form-urlencoded',
        },
    });
    const text = await response.json();
    return text;
  }
  getStakeLpUrl = (pair: string, uniswap?: string) => {
    const url = uniswap ? uniswap : config.mdexUrl;
    return `${url}#/add/${config.externalTokens[pair.split('/')[0]][0]}/${config.externalTokens[pair.split('/')[1]][0]}`;
  }
  getBuyTokenUrl = (pair: string, uniswap?: string) => {
    const url = uniswap ? uniswap : config.mdexUrl;
    return `${url}#/swap?inputCurrency=${config.externalTokens[pair.split('/')[0]][0]}&outputCurrency=${config.externalTokens[pair.split('/')[1]][0]}`;
  }
}
